// src/util/webSocketService.js

import { useUserStore } from '@/stores/user';
import { ElNotification } from 'element-plus';

const WEBSOCKET_URL = "ws://127.0.0.1:8080/globalWs/message";

// 存储不同消息类型的处理函数
// 例如: { 'new_post': [handler1, handler2], 'update_post': [handler3] }
const messageHandlers = new Map();
let socket = null;
let reconnectAttempts = 0;
const MAX_RECONNECT_ATTEMPTS = 5;
let heartBeatInterval = null;

const webSocketService = {
  connect() {
    const userStore = useUserStore();
    const token = userStore.token;

    if (!token) {
      console.error("WebSocket: 无法连接，用户未登录。");
      return;
    }

    // 防止重复连接
    if (socket && socket.readyState === WebSocket.OPEN) {
      console.log("WebSocket 已连接，无需重复操作。");
      return;
    }

    // 附带 Token 进行连接
    const urlWithToken = `${WEBSOCKET_URL}?token=${token}`;
    socket = new WebSocket(urlWithToken);

    socket.onopen = () => {
      console.log("WebSocket 连接成功！");
      reconnectAttempts = 0; // 重置重连尝试次数
      // 启动心跳机制
      this.startHeartbeat();
    };

    socket.onmessage = (event) => {
      try {
        const message = JSON.parse(event.data);
        console.log("收到 WebSocket 消息:", message);

        // 根据消息类型，调用所有注册的处理函数
        if (message.type && messageHandlers.has(message.type)) {
          messageHandlers.get(message.type).forEach(handler => handler(message.data));
        }
      } catch (error) {
        // 后端首次连接成功会发送非 JSON 字符串，这里我们友好地处理它
        if(event.data.includes("连接成功")){
            ElNotification({
                title: '实时通知服务',
                message: '已成功连接，您将收到实时更新。',
                type: 'success',
            });
        } else {
            console.error("处理 WebSocket 消息失败:", error);
        }
      }
    };

    socket.onclose = () => {
      console.warn("WebSocket 连接已关闭。");
      this.stopHeartbeat();
      // 尝试重连
      if (reconnectAttempts < MAX_RECONNECT_ATTEMPTS) {
        reconnectAttempts++;
        console.log(`将在 5 秒后尝试重新连接... (第 ${reconnectAttempts} 次)`);
        setTimeout(() => this.connect(), 5000);
      } else {
        console.error("已达到最大重连次数，请刷新页面重试。");
      }
    };

    socket.onerror = (error) => {
      console.error("WebSocket 发生错误:", error);
    };
  },

  // 注册消息处理函数
  on(messageType, handler) {
    if (!messageHandlers.has(messageType)) {
      messageHandlers.set(messageType, []);
    }
    messageHandlers.get(messageType).push(handler);
    console.log(`已为 "${messageType}" 注册新的处理函数。`);
  },

  // 注销消息处理函数
  off(messageType, handler) {
    if (messageHandlers.has(messageType)) {
      const handlers = messageHandlers.get(messageType);
      const index = handlers.indexOf(handler);
      if (index > -1) {
        handlers.splice(index, 1);
        console.log(`已从 "${messageType}" 注销一个处理函数。`);
      }
    }
  },
  subscribe(topic) {
    if (socket && socket.readyState === WebSocket.OPEN) {
      const message = {
        command: "subscribe",
        topic: topic
      };
      socket.send(JSON.stringify(message));
      console.log(`已发送 [subscribe] 命令，主题: ${topic}`);
    } else {
      console.error(`WebSocket 未连接，无法订阅主题: ${topic}`);
    }
  },

  // --- 新增 unsubscribe 方法 ---
  unsubscribe(topic) {
    if (socket && socket.readyState === WebSocket.OPEN) {
      const message = {
        command: "unsubscribe",
        topic: topic
      };
      socket.send(JSON.stringify(message));
      console.log(`已发送 [unsubscribe] 命令，主题: ${topic}`);
    } else {
      console.error(`WebSocket 未连接，无法取消订阅主题: ${topic}`);
    }
  },

  startHeartbeat() {
    this.stopHeartbeat(); // 先停止旧的，防止重复
    heartBeatInterval = setInterval(() => {
      if (socket && socket.readyState === WebSocket.OPEN) {
        socket.send(JSON.stringify({ command: 'heartbeat' }));
      }
    }, 30000); // 每30秒发送一次心跳
  },

  stopHeartbeat() {
    if (heartBeatInterval) {
      clearInterval(heartBeatInterval);
      heartBeatInterval = null;
    }
  },
  
  disconnect() {
      if (socket) {
          this.stopHeartbeat();
          reconnectAttempts = MAX_RECONNECT_ATTEMPTS; // 禁止重连
          socket.close();
          socket = null;
          console.log("WebSocket 已主动断开连接。");
      }
  }
};

export default webSocketService;